#ifndef SETUP_MODE_H
#define SETUP_MODE_H

#include "coopmode.h"
#include <windows.h>
#include <iostream> // debug

class SetupMode : public CooperativeMode
{
public:
	SetupMode() : CooperativeMode(cnc::base::OPMODE_SETUP) {}
	virtual void start()
	{
		uisrv_->selectForm("manual");
		uisrv_->setInfo("Axis group", ":)");
		createDebugConsoleWindow();
	}
	virtual bool execute()
	{
		cnc::comm::KbdCommand kbdCmd;
		if (vksrv_->getCommand(&kbdCmd)) {
			uisrv_->setCommand(kbdCmd);
			printCommand(kbdCmd);
			MessageBeep(0);
		}
		return true;
	}
	virtual void stop()
	{
	}
	void printCommand(const cnc::comm::KbdCommand &kbdCmd)
	{
		static char *idName[] = {
			"Character",
			"Keystroke",
			"Emergency",
			"Cycle",
			"Mode",
			"Option",
			"Feedrate Override",
			"Jog Feedrate",
			"Rapid Feedrate Override",
			"Axis",
			"Spindle",
			"Spindle Speed",
			"Spindle Override",
			"Handwheel",
			"Tool",
			"Device"
		};
		std::cout << idName[kbdCmd.getID()] << " = ";
		switch (kbdCmd.getID()) {
		case cnc::comm::CHARACTER::ID:
			std::cout << "'" << static_cast<char>(kbdCmd.getValue())
				<< "'" << std::endl;
			break;
		case cnc::comm::KEYSTROKE::ID:
			std::cout << kbdCmd.getValue() << std::endl;
			break;
		case cnc::comm::EMERGENCY::ID:
			switch (kbdCmd.getValue()) {
			case cnc::comm::EMERGENCY::STOP:
				std::cout << "Stop" << std::endl;
				break;
			case cnc::comm::EMERGENCY::CONTINUE:
				std::cout << "Continue" << std::endl;
				break;
			}
			break;
		case cnc::comm::CYCLE::ID:
			switch (kbdCmd.getValue()) {
			case cnc::comm::CYCLE::START:
				std::cout << "Start" << std::endl;
				break;
			case cnc::comm::CYCLE::FEED_HOLD:
				std::cout << "Feed hold" << std::endl;
				break;
			}
			break;
		case cnc::comm::MODE::ID:
			switch (kbdCmd.getValue()) {
			case cnc::comm::MODE::MEMORY:
				std::cout << "Memory" << std::endl;
				break;
			case cnc::comm::MODE::MDI:
				std::cout << "MDI" << std::endl;
				break;
			case cnc::comm::MODE::FILE_MANAGER:
				std::cout << "File Manager" << std::endl;
				break;
			case cnc::comm::MODE::EDITOR:
				std::cout << "Editor" << std::endl;
				break;
			case cnc::comm::MODE::HANDWHEEL:
				std::cout << "Handwheel" << std::endl;
				break;
			case cnc::comm::MODE::JOG:
				std::cout << "Jog" << std::endl;
				break;
			case cnc::comm::MODE::RAPID:
				std::cout << "Rapid" << std::endl;
				break;
			case cnc::comm::MODE::HOME:
				std::cout << "Home" << std::endl;
				break;
			}
			break;
		case cnc::comm::OPTION::ID:
			switch (kbdCmd.getValue()) {
			case cnc::comm::OPTION::SINGLE_BLOCK_OFF:
				std::cout << "Single Block Off" << std::endl;
				break;
			case cnc::comm::OPTION::SINGLE_BLOCK_ON:
				std::cout << "Single Block On" << std::endl;
				break;
			case cnc::comm::OPTION::OPTIONAL_STOP_OFF:
				std::cout << "Optional Stop Off" << std::endl;
				break;
			case cnc::comm::OPTION::OPTIONAL_STOP_ON:
				std::cout << "Optional Stop On" << std::endl;
				break;
			case cnc::comm::OPTION::BLOCK_SKIP_OFF:
				std::cout << "Block Skip Off" << std::endl;
				break;
			case cnc::comm::OPTION::BLOCK_SKIP_ON:
				std::cout << "Block Skip On" << std::endl;
				break;
			case cnc::comm::OPTION::DRY_RUN_OFF:
				std::cout << "Dry Run Off" << std::endl;
				break;
			case cnc::comm::OPTION::DRY_RUN_ON:
				std::cout << "Dry Run On" << std::endl;
				break;
			case cnc::comm::OPTION::MST_LOCK_OFF:
				std::cout << "MST Lock Off" << std::endl;
				break;
			case cnc::comm::OPTION::MST_LOCK_ON:
				std::cout << "MST Lock On" << std::endl;
				break;
			case cnc::comm::OPTION::MACHINE_LOCK_OFF:
				std::cout << "Machine Lock Off" << std::endl;
				break;
			case cnc::comm::OPTION::MACHINE_LOCK_ON:
				std::cout << "Machine Lock On" << std::endl;
				break;
			}
			break;
		case cnc::comm::FEEDRATE_OVERRIDE::ID:
			std::cout << kbdCmd.getValue() << "%" << std::endl;
			break;
		case cnc::comm::JOG_FEEDRATE::ID:
			std::cout << kbdCmd.getValue() << "mm/min (in/min)" << std::endl;
			break;
		case cnc::comm::RAPID_FEEDRATE_OVERRIDE::ID:
			std::cout << kbdCmd.getValue() << "%" << std::endl;
			break;
		case cnc::comm::AXIS::ID:
			switch (kbdCmd.getValue()) {
			case cnc::comm::AXIS::X_POSITIVE_IGNORE:
				std::cout << "X Axis Positive Ignore" << std::endl;
				break;
			case cnc::comm::AXIS::X_POSITIVE_SELECT:
				std::cout << "X Axis Positive Select" << std::endl;
				break;
			case cnc::comm::AXIS::X_NEGATIVE_IGNORE:
				std::cout << "X Axis Negative Ignore" << std::endl;
				break;
			case cnc::comm::AXIS::X_NEGATIVE_SELECT:
				std::cout << "X Axis Negative Select" << std::endl;
				break;
			case cnc::comm::AXIS::Y_POSITIVE_IGNORE:
				std::cout << "Y Axis Positive Ignore" << std::endl;
				break;
			case cnc::comm::AXIS::Y_POSITIVE_SELECT:
				std::cout << "Y Axis Positive Select" << std::endl;
				break;
			case cnc::comm::AXIS::Y_NEGATIVE_IGNORE:
				std::cout << "Y Axis Negative Ignore" << std::endl;
				break;
			case cnc::comm::AXIS::Y_NEGATIVE_SELECT:
				std::cout << "Y Axis Negative Select" << std::endl;
				break;
			case cnc::comm::AXIS::Z_POSITIVE_IGNORE:
				std::cout << "Z Axis Positive Ignore" << std::endl;
				break;
			case cnc::comm::AXIS::Z_POSITIVE_SELECT:
				std::cout << "Z Axis Positive Select" << std::endl;
				break;
			case cnc::comm::AXIS::Z_NEGATIVE_IGNORE:
				std::cout << "Z Axis Negative Ignore" << std::endl;
				break;
			case cnc::comm::AXIS::Z_NEGATIVE_SELECT:
				std::cout << "Z Axis Negative Select" << std::endl;
				break;
			}
			break;
		case cnc::comm::SPINDLE::ID:
			switch (kbdCmd.getValue()) {
			case cnc::comm::SPINDLE::NORMAL_ROTATION:
				std::cout << "Normal Rotation" << std::endl;
				break;
			case cnc::comm::SPINDLE::REVERSE_ROTATION:
				std::cout << "Reverse Rotation" << std::endl;
				break;
			case cnc::comm::SPINDLE::START:
				std::cout << "Start" << std::endl;
				break;
			case cnc::comm::SPINDLE::STOP:
				std::cout << "Stop" << std::endl;
				break;
			}
			break;
		case cnc::comm::SPINDLE_SPEED::ID:
			std::cout << kbdCmd.getValue() << "rpm" << std::endl;
			break;
		case cnc::comm::SPINDLE_OVERRIDE::ID:
			std::cout << kbdCmd.getValue() << "%" << std::endl;
			break;
		case cnc::comm::HANDWHEEL::ID:
			switch (kbdCmd.getValue()) {
			case cnc::comm::HANDWHEEL::FACTOR_1:
				std::cout << "x1" << std::endl;
				break;
			case cnc::comm::HANDWHEEL::FACTOR_10:
				std::cout << "x10" << std::endl;
				break;
			case cnc::comm::HANDWHEEL::FACTOR_100:
				std::cout << "x100" << std::endl;
				break;
			case cnc::comm::HANDWHEEL::DECREASE:
				std::cout << "Decrease" << std::endl;
				break;
			case cnc::comm::HANDWHEEL::INCREASE:
				std::cout << "Increase" << std::endl;
				break;
			case cnc::comm::HANDWHEEL::SELECT_AXIS_X:
				std::cout << "Select X Axis" << std::endl;
				break;
			case cnc::comm::HANDWHEEL::SELECT_AXIS_Y:
				std::cout << "Select Y Axis" << std::endl;
				break;
			case cnc::comm::HANDWHEEL::SELECT_AXIS_Z:
				std::cout << "Select Z Axis" << std::endl;
				break;
			}
			break;
		case cnc::comm::TOOL::ID:
			std::cout << kbdCmd.getValue() << std::endl;
			break;
		case cnc::comm::DEVICE::ID:
			std::cout << (kbdCmd.getValue() >> 4) << " ";
			switch (kbdCmd.getValue() & 0x0F) {
			case 0x00:
				std::cout << "Disabled" << std::endl;
				break;
			case 0x01:
				std::cout << "Enabled" << std::endl;
				break;
			case 0x02:
				std::cout << "Automatic" << std::endl;
				break;
			default:
				std::cout << "Error: " << (kbdCmd.getValue() & 0x0F) << std::endl;
			}
			break;
		}
	}
};

#endif
